// Copyright (c) 2019 Presto Labs Pte. Ltd.
// Author: jhkim
#pragma once

#include <string>

#include <boost/algorithm/string.hpp>

#include <nlohmann/json.hpp>

namespace impl {

// note: futures_currency_list is unused
const nlohmann::json Coin21DirMap = R"(
{
  "Futures.Binance.v1.l1_realtime": "Futures.Binance.l1_realtime",
  "Spot.Binance.v1.l1_realtime": "Spot.Binance.l1_realtime",
  "Futures.Okex.v3-swap.snapshot": "Futures.Okex.v3_swap",
  "Spot.Quoinex.v1.single_channel": "Spot.Quoinex.single_channel",
  "Futures.Okex.v3.realtime": "Futures.Okex.v3_realtime",
  "Spot.Quoinex.v2.realtime": "Spot.Quoinex.single_channel"
}
)"_json;


enum FastfeedPathResolveRule {
  UNKNOWN_RULE,
  COIN21_MAP,
  MEAR,
  MEA,
  MER,
  ME,
};

using coin2::exchange::base::market::ExchangeTypeToString;
using coin2::exchange::base::market::MarketTypeToString;

inline std::string ResolveFastfeedCacheDir(
    const MarketExchangeApiRecipe& mear,
    FastfeedPathResolveRule path_resolve_rule) {
  // Special handling to Spot.Bitflyer
  MarketExchangeApiRecipe mear_tmp = mear;
  if (mear.mea.exchange == coin::proto::ExchangeType::Bitflyer) {
    mear_tmp.mea.market = coin::proto::MarketType::Futures;
  }
  std::string coin2_style_dirname = mear_tmp.String();
  switch (path_resolve_rule) {
    case COIN21_MAP:
      if (Coin21DirMap.count(coin2_style_dirname) > 0) {
        return Coin21DirMap.at(coin2_style_dirname);
      } else {
        return "";
      }
    case MEAR:
      return mear_tmp.String();
    case MEA:
      return mear_tmp.mea.String();
    case MER:
      return fmt::format(
          "{}.{}.{}",
          MarketTypeToString(mear_tmp.mea.market),
          ExchangeTypeToString(mear_tmp.mea.exchange),
          mear_tmp.recipe);
    case ME:
      return fmt::format(
          "{}.{}",
          MarketTypeToString(mear_tmp.mea.market),
          ExchangeTypeToString(mear_tmp.mea.exchange));
    default:
      NOTREACHED();
      return "";
  }
}

// no point
inline std::string ResolveFastfeedMachine(
    const MarketExchangeApiRecipe& mear,
    const std::string& machine) {
  if (machine == "feed-best.ap-northeast-1.aws" ||
      machine == "feed-best.cn-hongkong.aliyun" ||
      machine == "feed-coin1.ap-northeast-1.aws" ||
      machine == "feed-coin1.cn-hongkong.aliyun") {
    std::string split;
    switch (mear.mea.exchange) {
      case coin::proto::ExchangeType::Okex:
        if (machine == "feed-coin1.ap-northeast-1.aws" ||
            machine == "feed-coin1.cn-hongkong.aliyun") {
          split = "02";
        } else {
          split = "05";
        }
        break;
      case coin::proto::ExchangeType::Huobi:
      case coin::proto::ExchangeType::Binance:
      case coin::proto::ExchangeType::Bitmex:
        if (machine == "feed-coin1.ap-northeast-1.aws" ||
            machine == "feed-coin1.cn-hongkong.aliyun") {
          split = "03";
        } else {
          split = "05";
        }
        break;
      default:
        split = "04";
    }
    LOG(INFO) << mear.String() << " " << boost::replace_all_copy(machine, "best", split);
    std::string ret = boost::replace_all_copy(machine, "best", split);
    ret = boost::replace_all_copy(ret, "coin1", split);
    return ret;
  } else {
    return boost::replace_all_copy(machine, "best", "01");
  }
}

}  // namespace impl

using impl::ResolveFastfeedCacheDir;
using impl::ResolveFastfeedMachine;
